/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 *
 */

import path from 'path';

import { hvigor } from '@ohos/hvigor';
import fse from 'fs-extra';

import { CommonConst } from '../../../const/common-const.js';
import { getJson5Obj } from '../../json-util.js';
import { OhosLogger } from '../../log/ohos-logger.js';
import { ValidateUtil } from '../../validate/validate-util.js';
import { ValidatorStore } from '../../validate/validator-store.js';
import { configFileLoader } from '../config-file-loader.js';

const log: OhosLogger = OhosLogger.getLogger('BuildProfileLoader');

export abstract class AbstractBuildProfileLoader {
  public abstract getBuildProfile(nodeName?: string): any;

  // 获取一个hvigorNode的buildProfile的内容
  protected getBuildProfileJson5Obj(hvigorNodeName: string, schemaCheck = true, classKind?: string): any {

    // 存在工程名与模块名相同的情况，仅靠 hvigorNodeName 可能取不到正确的 node，需要配合 node 的 classKind 来区分是 project 还是 module
    const hvigorNode = hvigor.getNodeByName(hvigorNodeName, classKind);
    if (hvigorNode === undefined) {
      log.printErrorExit('NODE_NOT_FOUND_BY_NODE_NAME', [hvigorNodeName]);
      return;
    }
    const buildProfileJson5Path = path.resolve(hvigorNode.getNodePath(), CommonConst.PROFILE_JSON5);

    const buildProfileJson5Obj = configFileLoader.getConfigFileJson(buildProfileJson5Path);
    if (buildProfileJson5Obj === undefined) {
      if (fse.existsSync(buildProfileJson5Path)) {
        // 如果是第一次加载，读取文件并应用可能的替换，将替换后的存入map
        let json5Obj = getJson5Obj(buildProfileJson5Path);
        json5Obj = this.initializeReplace(json5Obj);
        this.setBuildProfileJson5Obj(hvigorNodeName, json5Obj, schemaCheck);
        return json5Obj;
      } else {
        log.warn(`not found build-profile json file in : ${buildProfileJson5Path}`);
      }
    } else {
      return buildProfileJson5Obj;
    }
  }

  public abstract setBuildProfileJson5Obj(hvigorNodeName: string, buildProfileJson5Obj: any, schemaCheck: boolean): void;

  protected setBuildProfileJson5ObjCheck(hvigorNodeName: string, buildProfileJson5Obj: any, schemaPath: string | undefined, classKind?: string): void {
    const hvigorNode = hvigor.getNodeByName(hvigorNodeName, classKind);
    if (hvigorNode === undefined) {
      log.printErrorExit('NODE_NOT_FOUND_BY_NODE_NAME', [hvigorNodeName]);
      return;
    }
    const filePath = path.resolve(hvigorNode.getNodePath(), CommonConst.PROFILE_JSON5);
    configFileLoader.setConfigFileJson(filePath, buildProfileJson5Obj);
    schemaPath && this.validateBuildProfile(buildProfileJson5Obj, filePath, schemaPath);
  }

  protected validateBuildProfile(obj: object, filePath: string, schemaPath: string) {
    const validator = ValidatorStore.addValidator(schemaPath);
    try {
      ValidateUtil.schemaCheckJSObject(obj, undefined, validator);
    } catch (e) {
      if (e instanceof Error) {
        log.errorMessageExit(e.name, e.message);
      }
    }
  }

  protected initializeReplace(json5Obj: any) {
    // do nothing
    return json5Obj;
  }
}
